#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>

// // 前台进程和后台进程的区别：谁能获取键盘输入便是前台进程，否则是后台进程
// void myhandler(int signo)
// {
//     std::cout << "process get a signal: " << signo << std::endl;
// }
// int main()
// {
//     // SIGINT:2号信号
//     signal(SIGINT,myhandler);   // 只需要设置一次，往后都有效

//     // 测试1~31的普通信号，其中无法被signal捕捉的有：9(杀掉)和19(暂停)
//     for(int i = 1;i <= 31;i++)
//     {
//         signal(i,myhandler);
//     }
//     while(true)
//     {
//         std::cout << "I am a crazy process : " << getpid() << std::endl;
//         sleep(1);
//     }

//     return 0;
// }


// void handler(int signo)
// {
//     std::cout << "...get a sig, number: " << signo << std::endl;
// }

// int main()
// {
//     signal(SIGFPE,handler);
//     std::cout << "div before" << std::endl;

//     sleep(5);
//     int a = 10;
//     a /= 0;
//     std::cout << "div after" << std::endl;
//     sleep(1);

//     return 0;
// }


// void handler(int signo)
// {
//     std::cout << "...get a sig, number: " << signo << std::endl;

//     // alarm：闹钟，由于是同一个接口，所以在第二次调用后，返回第一次闹钟的剩余时间
//     int n = alarm(5);
//     std::cout << "剩余时间：" << n << std::endl;
// }
// int main()
// {
//     signal(SIGALRM,handler);
//     int n = alarm(50);

//     while(1)
//     {
//         std::cout << "proc is running: " << getpid() << std::endl;

//         sleep(1);
//     }
//     return 0;
// }


int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        // child
        int cnt = 5;
        while(cnt)
        {
            std::cout << "I am a child process, pid: " << getpid() << "cnt: " << cnt << std::endl;
            sleep(1);
            cnt--;
        }
    }
    else if(id > 0)
    {
        int status = 0;
        pid_t rid = waitpid(id,&status,0);
        if(rid = id)
        {
            // 正常退出时：低16位的8~15位表示退出状态，0~7为0
            // 被信号杀掉时：0~7位表示终止信号，第8位表示退出码
            std::cout << "child quit info, rid: " << rid 
                      << " exit code: " << ((status>>8)&0xFF) 
                      << " exit signal: " << (status&0x7F)
                      << " core dump: " << ((status>>7)&1)
                      << std::endl;
        }
    }
    return 1;
}